package miroshnichenko.gallery.dao.database;

import miroshnichenko.gallery.dao.UserDao;
import miroshnichenko.gallery.domain.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;

@Repository
public class UserDaoJdbcTemplate implements UserDao {

    private Logger log = LoggerFactory.getLogger(UserDaoJdbcTemplate.class);

    private static final String ADD_USER = "INSERT INTO users (first_name, last_name, email, password, admin_rights) " +
            "VALUES (:firstName, :lastName, :email, :password, :adminRights)";
    private static final String GET_USER_BY_EMAIL = "SELECT * FROM users WHERE email = :email";

    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    @Override
    public void addUser(User user) {
        SqlParameterSource params = new BeanPropertySqlParameterSource(user);
        jdbcTemplate.update(ADD_USER, params);
    }

    @Override
    public User getUserByEmail(String email) {
        User user = null;
        try {
            SqlParameterSource paramSource = new MapSqlParameterSource("email", email);
            user = jdbcTemplate.queryForObject(GET_USER_BY_EMAIL, paramSource, userMapper);
        } catch (EmptyResultDataAccessException ex) {
            log.info("Requested email not found.");
        }
        return user;
    }

    private final RowMapper<User> userMapper = new RowMapper<User>() {

        @Override
        public User mapRow(ResultSet resultSet, int rowNum) throws SQLException {
            User user = new User();

            user.setFirstName(resultSet.getString("first_name"));
            user.setLastName(resultSet.getString("last_name"));
            user.setEmail(resultSet.getString("email"));
            user.setPassword(resultSet.getString("password"));
            user.setAdminRights(resultSet.getBoolean("admin_rights"));

            return user;
        }
    };
}
